package com.mingqijia.gassafety.webserver.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gap.basic.base.CommonResponse;
import com.gap.basic.exception.BizException;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.mingqijia.gassafety.db.entity.*;
import com.mingqijia.gassafety.db.entity.vo.ConsumerFuncAreaVo;
import com.mingqijia.gassafety.db.entity.vo.FuncAreaVO;
import com.mingqijia.gassafety.db.mapper.ConsumerLocationMapper;
import com.mingqijia.gassafety.db.mapper.ConsumerMapper;
import com.mingqijia.gassafety.db.mapper.FieldTemplateMapper;
import com.mingqijia.gassafety.db.mapper.FuncAreaMapper;
import com.mingqijia.gassafety.shared.constant.Constants;
import com.mingqijia.gassafety.shared.constant.StrategyTypeEnum;
import com.mingqijia.gassafety.shared.dto.LogVO;
import com.mingqijia.gassafety.shared.dto.UserFuncCodePermissionDTO;
import com.mingqijia.gassafety.shared.utils.ApplicationUtils;
import com.mingqijia.gassafety.webserver.dto.AdInfoDTO;
import com.mingqijia.gassafety.webserver.request.BusinessAreaListRequest;
import com.mingqijia.gassafety.webserver.request.FuncAreaAddRequest;
import com.mingqijia.gassafety.webserver.request.FuncAreaEditRequest;
import com.mingqijia.gassafety.webserver.request.FuncAreaQueryRequest;
import com.mingqijia.gassafety.webserver.response.*;
import com.mingqijia.gassafety.webserver.response.baidu.BaiDuDetailResp;
import com.mingqijia.gassafety.webserver.service.ConsumerLocationService;
import com.mingqijia.gassafety.webserver.service.FunctionAreaService;
import com.mingqijia.gassafety.webserver.service.OrganizationService;
import com.mingqijia.gassafety.webserver.service.UserPermissionService;
import com.mingqijia.gassafety.webserver.utils.CoordinatesTransitionUtil;
import com.mingqijia.gassafety.webserver.utils.LogRecordAspect;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.geom.LinearRing;
import org.locationtech.jts.geom.Polygon;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.mingqijia.gassafety.shared.constant.TableConst.consumer;

/**
 * 功能区
 * @Author: duanhongxiang
 * @Date: 2024/6/13 21:31
 */
@Service
@Slf4j
public class FunctionAreaServiceImpl extends ServiceImpl<FuncAreaMapper, FuncArea> implements FunctionAreaService {
    @Autowired
    OrganizationService organizationService;

    @Autowired
    FieldTemplateMapper fieldTemplateMapper;

    @Autowired
    ConsumerLocationMapper consumerLocationMapper;

    @Autowired
    ConsumerMapper consumerMapper;

    @Autowired
    ConsumerLocationService consumerLocationService;

    @Autowired
    UserPermissionService userPermissionService;

    @Value("${baidu.maps.key}")
    private String baiDuMapsKey;

    @Override
    public List<FuncAreaTreeResponse> treeList() {
        String spId = ApplicationUtils.getWorkingSpId();

        FieldTemplate fieldTemplate = fieldTemplateMapper.getTypeBySpId(spId);
        if( Constants.FUNC_AREA_ALLOCAT_AUTO.equals(fieldTemplate.getFuncAreaAllocat()) ){//自动分配
            return getAutoTreeList(spId);
        }else{//自定义分配
            List<FuncArea> list = this.baseMapper.treeList(spId);
            List<FuncAreaTreeResponse> responseList = new ArrayList<>();
            if(null!=list && list.isEmpty()){
                return responseList;
            }
            UserFuncCodePermissionDTO userFuncCodePermission = userPermissionService.getUserDepartPermission(
                    ApplicationUtils.getHeaderSpId(),
                    ApplicationUtils.getUserId()
            );
            List<String> consumerFuncCodes = new ArrayList<>();
            if (null != userFuncCodePermission.getFuncCodes() && !userFuncCodePermission.getFuncCodes().isEmpty()) {
                List<ConsumerFuncAreaVo> consumerFuncAreaVos = consumerMapper.getConsumersFuncAreaCodes(ApplicationUtils.getWorkingSpId(), userFuncCodePermission.getFuncCodes());
                for (ConsumerFuncAreaVo consumerFuncAreaVo : consumerFuncAreaVos) {
                    if (StringUtils.isNotEmpty(consumerFuncAreaVo.getCityCode()) && !consumerFuncCodes.contains(consumerFuncAreaVo.getCityCode())) {
                        consumerFuncCodes.add(consumerFuncAreaVo.getCityCode());
                    }
                    if (StringUtils.isNotEmpty(consumerFuncAreaVo.getDistrictCode()) && !consumerFuncCodes.contains(consumerFuncAreaVo.getDistrictCode())) {
                        consumerFuncCodes.add(consumerFuncAreaVo.getDistrictCode());
                    }
                    if (StringUtils.isNotEmpty(consumerFuncAreaVo.getTownCode()) && !consumerFuncCodes.contains(consumerFuncAreaVo.getTownCode())) {
                        consumerFuncCodes.add(consumerFuncAreaVo.getTownCode());
                    }
                }
            }
            Map<Integer,List<FuncArea>> funcAreaMap = new HashMap<>();
            for (FuncArea item:list) {
                List<FuncArea> items;
                if (funcAreaMap.containsKey(item.getPid())) {
                    items = funcAreaMap.get(item.getPid());
                }else{
                    items = new ArrayList<>();
                }
                items.add(item);
                funcAreaMap.put(item.getPid(),items);
            }
            return getTreeList(funcAreaMap,0,userFuncCodePermission.getFuncCodes(),consumerFuncCodes);
        }
    }

    /**
     * @Method List
     * @Author zm
     * @Description 查询区域管理 功能区，街道，商圈树形列表
     * @Date 2024/7/9 15:51
    */
    @Override
    public List<FuncAreaListResponse> List(FuncAreaQueryRequest request) {
        String spId = ApplicationUtils.getWorkingSpId();
        List<FuncAreaListResponse> responseList = new ArrayList<>();
        log.info("spId:{}",spId);
        FieldTemplate fieldTemplate = fieldTemplateMapper.getTypeBySpId(spId);
        //自定义分配 非自定义分配则为空
        if(!Constants.FUNC_AREA_ALLOCAT_AUTO.equals(fieldTemplate.getFuncAreaAllocat()) ) {
            //数据权限
            UserFuncCodePermissionDTO userFuncCodePermission = userPermissionService.getUserDepartPermission(
                    ApplicationUtils.getHeaderSpId(),
                    ApplicationUtils.getUserId()
            );
            List<Integer> funcIds = userFuncCodePermission.getFuncIds();
            LambdaQueryWrapper<FuncArea> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(FuncArea::getSpId,spId);
            queryWrapper.eq(FuncArea::getIsDeleted,false);
            if (request != null) {
                if (StringUtils.isNotEmpty(request.getFuncName())) {
                    queryWrapper.like(FuncArea::getFuncName, request.getFuncName());
                }
                if (request.getLevel() != null) {
                    if (request.getLevel() == 1) {
                        queryWrapper.eq(FuncArea::getLevel, 1);
                    } else if (request.getLevel() == 2) {
                        queryWrapper.eq(FuncArea::getLevel, 2);
                    } else if (request.getLevel() == 3) {
                        queryWrapper.eq(FuncArea::getLevel, 3);
                    }
                }
            }
            if( null!=funcIds && !funcIds.isEmpty() ){
                queryWrapper.in(FuncArea::getId,funcIds);
            }
            queryWrapper.orderByAsc(FuncArea::getOrdinal).orderByAsc(FuncArea::getId);
            List<FuncArea> list = this.baseMapper.selectList(queryWrapper);
            if( list.size() == 0 ) {
                return responseList;
            }
            return buildTree(list.stream().map(item -> {
                FuncAreaListResponse resp = new FuncAreaListResponse();
                BeanUtils.copyProperties(item,resp);
                return resp;
            }).collect(Collectors.toList()));
        }
        return responseList;
    }

   /**
    * @Method selectList
    * @Author zm
    * @Description selectList
    * @Date 2024/7/12 14:23
   */
    @Override
    public List<FuncAreaDetailResponse> selectList(Integer level) {
        String spId = ApplicationUtils.getWorkingSpId();
        //数据权限
        UserFuncCodePermissionDTO userFuncCodePermissionDTO = userPermissionService.getUserDepartPermission(
                spId,
                ApplicationUtils.getUserId()
        );
        List<Integer> funcIds = userFuncCodePermissionDTO.getFuncIds();

        LambdaQueryWrapper<FuncArea> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(FuncArea::getSpId,spId)
                .eq(FuncArea::getIsDeleted,false);
        if(null != level && level > 0) {
            queryWrapper.eq(FuncArea::getLevel,level);
        }
        else {
            queryWrapper.in(FuncArea::getLevel,Arrays.asList(1, 2));
        }
        if( null!=funcIds && !funcIds.isEmpty() ){
            queryWrapper.in(FuncArea::getId,funcIds);
        }
        queryWrapper.orderByAsc(FuncArea::getOrdinal).orderByAsc(FuncArea::getId);
        List<FuncArea> list = this.baseMapper.selectList(queryWrapper);

        return CollectionUtils.isNotEmpty(list) ? list.stream().map(item -> {
            FuncAreaDetailResponse resp = new FuncAreaDetailResponse();
            BeanUtils.copyProperties(item, resp);
            return resp;
        }).collect(Collectors.toList()) : new ArrayList<>();
    }

    /**
     * @Method add
     * @Author zm
     * @Description add
     * @Date 2024/7/12 14:20
    */
    @Override
    public CommonResponse<Boolean> add(FuncAreaAddRequest req) {
        String spId = ApplicationUtils.getWorkingSpId();

        UserFuncCodePermissionDTO userFuncCodePermission = userPermissionService.getUserDepartPermission(spId,ApplicationUtils.getUserId());
        if (1==userFuncCodePermission.getAuthority()){
            throw new BizException("没有该操作权限");
        }

        CommonResponse<Boolean> check =  checkRepeat(spId, req ,null);
        if (check.getCode() != 0) return check;

        //新增
        FuncArea saveEntity = new FuncArea();
        BeanUtil.copyProperties(req,saveEntity);
        saveEntity.setSpId(spId);
        saveEntity.setIsDeleted(false);
        saveEntity.setCreatedAt(new Date());
        // 校验
        Polygon currentPolygon = createPolygonFromCoordinates(req.getFence());
        check = checkFence(spId,currentPolygon,req, null);
        if (check.getCode() != 0) return check;
        if (null != currentPolygon) saveEntity.setBoundaryStr(currentPolygon.toString());

        this.baseMapper.insertArea(saveEntity);
        log.info("saveEntity.getId:{}",saveEntity.getId());
        LambdaUpdateWrapper<FuncArea> updateWrapper = new LambdaUpdateWrapper<>();
        if ( null != saveEntity.getId() && saveEntity.getId() > 0) {
            updateWrapper.eq(FuncArea::getId,saveEntity.getId()).
                    set(FuncArea::getFuncCode,AutoFuncCode(req.getLevel(),saveEntity.getId()));
            this.update(updateWrapper);
        }
        else {
            // 没有id时，查询func_code为Null或空字符串的数据，并更新func_code，进行补救措施
            this.baseMapper.repairFuncCode();
        }
        return CommonResponse.success(true);
    }

    /**
     * @Method isOverlap
     * @Author zm
     * @Description isOverlap
     * @Date 2024/7/10 11:34
     */
    public CommonResponse<Boolean> checkRepeat(String spId, FuncAreaAddRequest req, Integer oldId) {
        //校验名称重复
        LambdaQueryWrapper<FuncArea> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(FuncArea::getSpId,spId)
                .eq(FuncArea::getFuncName,req.getFuncName())
                .eq(FuncArea::getIsDeleted,false);
        if (null != oldId) queryWrapper.ne(FuncArea::getId,oldId);
        if (CollectionUtils.isNotEmpty(this.baseMapper.selectList(queryWrapper))) return CommonResponse.failure("区域名称重复",false);
        return CommonResponse.success(true);
    }


    /**
     * @Method isOverlap
     * @Author zm
     * @Description isOverlap
     * @Date 2024/7/10 11:34
     */
    public CommonResponse<Boolean> checkFence(String spId,Polygon currentPolygon, FuncAreaAddRequest req, Integer oldId) {
        if (req.getLevel() - 2 == 0  && req.getPid() == 0) {
            return CommonResponse.failure("区域类型为街道时,父级区域必填");
        }
        // 存在父级
        if (req.getPid() > 0) {
            if (req.getLevel() - 1 == 0) return CommonResponse.failure("功能区不可以设置父级区域",false);;
            LambdaQueryWrapper<FuncArea> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(FuncArea::getId, req.getPid())
                    .eq(FuncArea::getIsDeleted, false);
//            if (!StringUtils.isEmpty(req.getFence())) {
//                queryWrapper.isNotNull(FuncArea::getFence).
//                        ne(FuncArea::getFence, "");
//            }

            FuncArea funcArea = this.baseMapper.selectOne(queryWrapper);
            if (null == funcArea) return CommonResponse.failure("未找到父级区域",false);
            if (!StringUtils.isEmpty(req.getFence()) && StringUtils.isEmpty(funcArea.getFence())) return CommonResponse.failure("父级区域围栏未设置",false);
            // 校验区域类型与父级是否匹配
            if (req.getLevel() - funcArea.getLevel() != 1)  return CommonResponse.failure("区域类型错误，请检查",false);

            // 校验围栏是否在父级围栏中
//            if (StringUtils.isNotEmpty(funcArea.getFence()) && null != currentPolygon) {
//                boolean isContains = createPolygonFromCoordinates(funcArea.getFence()).contains(currentPolygon);
//                if (!isContains) return CommonResponse.failure("该围栏不在父级围栏内",false);
//            }
        }
//        if (null != currentPolygon) {
//            // 校验同级围栏是否重叠
//            LambdaQueryWrapper<FuncArea> peerQueryWrapper = new LambdaQueryWrapper<>();
//            peerQueryWrapper.eq(FuncArea::getSpId, spId)
//                    .eq(FuncArea::getPid,req.getPid())
//                    .eq(FuncArea::getIsDeleted,false)
//                    .isNotNull(FuncArea::getFence)
//                    .ne(FuncArea::getFence,"");
//            //  编辑时不包含当前围栏
//            if (null != oldId) peerQueryWrapper.ne(FuncArea::getId,oldId);
//            List<FuncArea> funcAreas = this.baseMapper.selectList(peerQueryWrapper);
//            if (CollectionUtils.isNotEmpty(funcAreas) && isOverlap(currentPolygon, funcAreas)) return CommonResponse.failure("围栏与已有围栏重叠或交叉,请修改",false);
//        }

        return CommonResponse.success(true);
    }

    /**
     * @Method isOverlap
     * @Author zm
     * @Description isOverlap
     * @Date 2024/7/10 11:34
    */
    public boolean isOverlap(Polygon currentFence, List<FuncArea> peerList) {
        boolean isOverlap = false;
        for (FuncArea fence : peerList) {
            log.info("fence.getFence:{}",fence.getFence());
            if (StringUtils.isEmpty(fence.getFence())) continue;
            Polygon existingFencePolygon = createPolygonFromCoordinates(fence.getFence());
            if (currentFence.intersects(existingFencePolygon)) {
                isOverlap = true;
                break;
            }
        }
        return isOverlap;
    }

    /**
     * @Method createPolygonFromCoordinates
     * @Author zm
     * @Description createPolygonFromCoordinates
     * @Date 2024/7/10 11:33
     */
    public Polygon createPolygonFromCoordinates (String fenceStr) {
        if (StringUtils.isEmpty(fenceStr)) return null;
        String[] parts = fenceStr.split(";");
        List<Coordinate> coordinates = new ArrayList<>();
        for (String part : parts) {
            String[] xy = part.split(",");
            double x = Double.parseDouble(xy[0]);
            double y = Double.parseDouble(xy[1]);
            coordinates.add(new Coordinate(x, y));
        }
        coordinates.add(coordinates.get(0));
        LinearRing linearRing = new GeometryFactory().createLinearRing(coordinates.toArray(new Coordinate[0]));
        return new GeometryFactory().createPolygon(linearRing, null);
    }

    /**
     * @Method AutoFuncCode
     * @Author zm
     * @Description AutoFuncCode
     * @Date 2024/7/10 11:34
    */
    public String AutoFuncCode(Integer level,Integer id) {
        log.info("AutoFuncCode.id:{}",id);
        String funcCode = "";
        switch (level) {
            case 2:
                funcCode = "S" + id;
                break;
            case 3:
                funcCode = "SQ" + id;
                break;
            default:
                funcCode = "D" + id;
                break;
        }
        log.info("AutoFuncCode.funcCode:{}",funcCode);
        return funcCode;
    }

    /**
     * @Method edit
     * @Author zm
     * @Description edit
     * 客户表影响：
     * 编辑功能区时 level=1： 更新功能区code与名称
     * 编辑街道时  level=2： 更新功能区code与名称  更新街道code与名称
     * 编辑商圈时 level=3： 更新功能区code与名称   更新街道code与名称   更新商圈code与名称
     * @Date 2024/7/10 21:47
    */
    @Override
    public CommonResponse<Boolean> edit(FuncAreaEditRequest req) {
        String spId = ApplicationUtils.getWorkingSpId();
        UserFuncCodePermissionDTO userFuncCodePermission = userPermissionService.getUserDepartPermission(spId,ApplicationUtils.getUserId());
        if (1==userFuncCodePermission.getAuthority()){
            throw new BizException("没有该操作权限");
        }
        FuncArea currentArea = this.getById(req.getId());
        if (null == currentArea || currentArea.getIsDeleted()) return CommonResponse.failure("记录不存在",false);

        // 关联之后区域类型不可编辑
        if (req.getLevel() - currentArea.getLevel() != 0 && currentArea.getPid() != 0) return CommonResponse.failure("当前区域已关联不可编辑",false);

        // 校验重复
        CommonResponse<Boolean> check =  checkRepeat(spId, req, req.getId());
        if (check.getCode() != 0) return check;
        //新增
        Date currentDate = new Date();
        FuncArea saveEntity = new FuncArea();
        BeanUtil.copyProperties(req,saveEntity);
        // 校验
        Polygon currentPolygon = createPolygonFromCoordinates(req.getFence());
        check = checkFence(spId,currentPolygon,req, req.getId());
        if (check.getCode() != 0) return check;
        if (null != currentPolygon) saveEntity.setBoundaryStr(currentPolygon.toString());
        saveEntity.setId(req.getId());
        saveEntity.setUpdatedAt(currentDate);
        saveEntity.setFuncCode(currentArea.getFuncCode());


        // 更新customer_location表
        FuncAreaVO funcAreaVO = new FuncAreaVO();
        funcAreaVO.setLevel(currentArea.getLevel());
        funcAreaVO.setFuncCode(currentArea.getFuncCode());
        funcAreaVO.setFuncName(currentArea.getFuncName());
        if (req.getPid() > 0) {
            LambdaQueryWrapper<FuncArea> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(FuncArea::getId,req.getPid())
                    .eq(FuncArea::getIsDeleted,false);
            FuncArea distinct = this.baseMapper.selectOne(queryWrapper);
            if (req.getLevel() - 2 == 0) {
                funcAreaVO.setCityFuncCode(distinct.getFuncCode());
                funcAreaVO.setCityFuncName(distinct.getFuncName());
            }
            else {
                funcAreaVO.setDistrictFuncCode(distinct.getFuncCode());
                funcAreaVO.setDistrictFuncName(distinct.getFuncName());
                if (distinct.getPid() > 0) {
                    queryWrapper.clear();
                    queryWrapper.eq(FuncArea::getId, distinct.getPid())
                            .eq(FuncArea::getIsDeleted,false);
                    FuncArea area = this.baseMapper.selectOne(queryWrapper);
                    funcAreaVO.setCityFuncCode(area.getFuncCode());
                    funcAreaVO.setCityFuncName(area.getFuncName());
                }
            }


        }
        currentArea.setResetChildCodes(Collections.singletonList(currentArea.getFuncCode()));
        List<Integer> ids = consumerLocationMapper.getCustomerLocationIdsByFuncCode(currentArea);

        this.baseMapper.updateArea(saveEntity);

        log.info("编辑：ids:{}",ids);
        if (CollectionUtils.isNotEmpty(ids)) {
            LambdaUpdateWrapper<ConsumerLocation> locationLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
            locationLambdaUpdateWrapper.in(ConsumerLocation::getId,ids)
                    .set(ConsumerLocation::getUpdatedAt,currentDate);
                /**
                 *  更改名称与pid场景:
                 *  level = 1  更新 cityName
                 *  level = 2  更新 distinctName
                 *  level = 3   更新 townName
                 */
                if (req.getLevel() - 1 == 0) {
                    locationLambdaUpdateWrapper.set(ConsumerLocation::getCity,req.getFuncName());
                }
                else if (req.getLevel() - 2 == 0) {
                    locationLambdaUpdateWrapper.set(ConsumerLocation::getDistrict,req.getFuncName());
                }
                else if (req.getLevel() - 3 == 0) {
                    locationLambdaUpdateWrapper.set(ConsumerLocation::getTownship,funcAreaVO.getFuncName());
                }else {
                    locationLambdaUpdateWrapper.eq(ConsumerLocation::getId,null);
                }
            consumerLocationMapper.update(null,locationLambdaUpdateWrapper);
        }

        //企业级操作日志
        LogVO vo = new LogVO();
        StringBuilder sb = new StringBuilder();
        if (StringUtils.isNotEmpty(currentArea.getFuncName()) && !currentArea.getFuncName().equals(req.getFuncName())) {
            sb.append("\n 功能区名称：由【").append(currentArea.getFuncName()).append("】变更为【").append(req.getFuncName()).append("】");
        }
        if (StringUtils.isEmpty(currentArea.getFence()) && StringUtils.isNotEmpty(req.getFence())) {
            sb.append("\n 新增围栏");
        } else if (StringUtils.isNotEmpty(currentArea.getFence()) && StringUtils.isEmpty(req.getFence())){
            sb.append("\n 删除围栏");
        } else if (StringUtils.isNotEmpty(currentArea.getFence()) && StringUtils.isNotEmpty(req.getFence()) && !currentArea.getFence().equals(req.getFence())){
            sb.append("\n 修改围栏");
        }
        String commomInfo =  req.getFuncName() ;
        vo.setDetail(sb.toString());
        vo.setCommonInfo(commomInfo);
        vo.setStrategyType("编辑");
        LogRecordAspect.threadLocal.set(vo);

        return CommonResponse.success(true);
    }

    /**
     * @Method detail
     * @Author zm
     * @Description detail
     * @Date 2024/7/11 14:02
    */
    @Override
    public CommonResponse<FuncAreaDetailResponse> detail(Integer id) {
        FuncAreaDetailResponse response = new FuncAreaDetailResponse();
        FuncArea funcArea =  this.getById(id);
        if (null == funcArea || funcArea.getIsDeleted()) return CommonResponse.failure("记录不存在",null);
        BeanUtils.copyProperties(funcArea,response);
        return CommonResponse.success(response);
    }

    /**
     * @Method delete
     * @Author zm
     * @Description delete
     * 客户表影响：
     * 删除功能区时 level=1： 置空功能区code与名称  置空街道code与名称
     * 删除街道时  level=2： 置空功能区code与名称  置空街道code与名称
     * 删除商圈时 level=3： 置空商圈code与名称
     * @Date 2024/7/11 14:02
    */
    @Override
    public CommonResponse<Boolean> delete(Integer id) {
        UserFuncCodePermissionDTO userFuncCodePermission = userPermissionService.getUserDepartPermission(ApplicationUtils.getHeaderSpId(),ApplicationUtils.getUserId());
        if (1==userFuncCodePermission.getAuthority()){
            throw new BizException("没有该操作权限");
        }
        FuncArea currentArea = this.getById(id);
        if (null == currentArea || currentArea.getIsDeleted()) return CommonResponse.failure("记录不存在",false);
        List<Integer> deleteIds = new ArrayList<>();
        List<Integer> resetIds = new ArrayList<>();
        /**
         *  删除功能区时 level=1： areaCode为功能区code  resetChildCodes 为 街道code
         *  删除街道时  level=2： resetChildCodes 为 街道code
         *  删除商圈时 level=3： resetChildCodes 为 商圈code
         */
        List<String>  resetChildCodes = new ArrayList<>();
         // 删除当前区域
         deleteIds.add(id);
         resetChildCodes.add(currentArea.getFuncCode());

         if (currentArea.getLevel() - 1 == 0 || currentArea.getLevel() - 2 == 0 ) {
             LambdaQueryWrapper<FuncArea> queryWrapper = new LambdaQueryWrapper<>();
             queryWrapper.eq(FuncArea::getPid,id).eq(FuncArea::getIsDeleted,false);
             List<FuncArea>  children = this.baseMapper.selectList(queryWrapper);
             if (CollectionUtils.isNotEmpty(children)) {
                 List<Integer> childIds = children.stream().map(FuncArea::getId).collect(Collectors.toList());
                 // 删除功能区时，删除关联的街道
                 if (currentArea.getLevel() - 1 == 0) {
                     deleteIds.addAll(childIds);
                 }
                 if (CollectionUtils.isNotEmpty(childIds)) {
                     LambdaQueryWrapper<FuncArea> tradeQueryWrapper = new LambdaQueryWrapper<>();
                     // 查询商圈
                     tradeQueryWrapper.eq(FuncArea::getIsDeleted,false)
                             .eq(FuncArea::getLevel,3).in(FuncArea::getPid,childIds);
                     List<FuncArea>  district = this.baseMapper.selectList(tradeQueryWrapper);
                     // 释放商圈的关联关系
                     if (CollectionUtils.isNotEmpty(district)) {
                         resetIds = district.stream().map(FuncArea::getId).collect(Collectors.toList());
                     }
                 }
             }
         }

        Date currentDate = new Date();
        LambdaUpdateWrapper<FuncArea> updateWrapper = new LambdaUpdateWrapper<>();
        log.info("删除功能区：deleteIds:{};resetIds:{}",resetChildCodes,currentArea);
         if (CollectionUtils.isNotEmpty(deleteIds)) {
             updateWrapper.in(FuncArea::getId,deleteIds)
                     .set(FuncArea::getIsDeleted,true)
                     .set(FuncArea::getUpdatedAt,currentDate);
             this.update(updateWrapper);
         }
        if (CollectionUtils.isNotEmpty(resetIds)) {
            updateWrapper.clear();
            updateWrapper.in(FuncArea::getId,resetIds)
                    .set(FuncArea::getPid,0)
                    .set(FuncArea::getUpdatedAt,currentDate);
            this.update(updateWrapper);
        }
        log.info("删除功能区：resetChildCodes:{};currentArea:{}",resetChildCodes,currentArea);
        //更新customer_location表
        if (CollectionUtils.isNotEmpty(resetChildCodes) && null != currentArea.getLevel()
                && currentArea.getLevel() >= 1 && currentArea.getLevel() <=3 ) {
            currentArea.setResetChildCodes(resetChildCodes);
            List<Integer> ids = consumerLocationMapper.getCustomerLocationIdsByFuncCode(currentArea);
            if (CollectionUtils.isNotEmpty(ids)) {
                LambdaUpdateWrapper<ConsumerLocation> locationLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
                locationLambdaUpdateWrapper.in(ConsumerLocation::getId,ids);
                if (currentArea.getLevel() - 3 == 0) {
                    // 置空商圈
                    locationLambdaUpdateWrapper.set(ConsumerLocation::getTownship,null)
                            .set(ConsumerLocation::getTowncode,null)
                            .set(ConsumerLocation::getUpdatedAt,currentDate);
                }
                else if (currentArea.getLevel() - 1 == 0){
                    // 置空功能区与街道
                    locationLambdaUpdateWrapper.set(ConsumerLocation::getCity,null)
                            .set(ConsumerLocation::getCitycode,null)
                            .set(ConsumerLocation::getDistrict,null)
                            .set(ConsumerLocation::getAdcode,null)
                            .set(ConsumerLocation::getUpdatedAt,currentDate);
                }
                else {
                    // 置空街道
                    locationLambdaUpdateWrapper.set(ConsumerLocation::getDistrict,null)
                            .set(ConsumerLocation::getAdcode,null)
                            .set(ConsumerLocation::getUpdatedAt,currentDate);
                }
                 consumerLocationMapper.update(null,locationLambdaUpdateWrapper);
            }
            //修改客户中的编码
            List<Integer> idsByFuncCode = consumerMapper.getCustomerLocationIdsByFuncCode(currentArea);
            if (CollectionUtils.isNotEmpty(idsByFuncCode)) {
                LambdaUpdateWrapper<Consumer> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
                lambdaUpdateWrapper.in(Consumer::getId,idsByFuncCode);
                if (currentArea.getLevel() - 3 == 0) {
                    // 置空商圈
                    lambdaUpdateWrapper.set(Consumer::getTowncode,null)
                            .set(Consumer::getUpdatedAt,currentDate);
                }
                else if (currentArea.getLevel() - 1 == 0){
                    // 置空功能区与街道
                    lambdaUpdateWrapper.set(Consumer::getCitycode,null)
                            .set(Consumer::getDistrictcode,null)
                            .set(Consumer::getUpdatedAt,currentDate);
                }
                else {
                    // 置空街道
                    lambdaUpdateWrapper.set(Consumer::getDistrictcode,null)
                            .set(Consumer::getUpdatedAt,currentDate);
                }
                consumerMapper.update(null,lambdaUpdateWrapper);
            }
        }
        //企业级操作日志
        LogVO vo = new LogVO();
        String detail = "删除【" + currentArea.getFuncName() + "】";
        String commomInfo =  currentArea.getFuncName() ;
        vo.setDetail(detail);
        vo.setCommonInfo(commomInfo);
        vo.setStrategyType("删除");
        LogRecordAspect.threadLocal.set(vo);
        return CommonResponse.success(true);
    }

    /**
     * @Method relationInfo
     * @Author zm
     * @Description 当前区域关联数量信息
     * @Date 2024/7/11 13:51
    */
    @Override
    public CommonResponse<FuncAreaRelationInfoResponse> relationInfo(Integer id) {
        FuncAreaRelationInfoResponse response = new FuncAreaRelationInfoResponse();
        FuncArea currentArea = this.getById(id);
        if (null == currentArea || currentArea.getIsDeleted()) return CommonResponse.failure("记录不存在",response);

        Integer ccbf = consumerLocationMapper.getRelationCustomerNum(currentArea);
        response.setRelationCustomerNum(ccbf == null ? 0 : ccbf);
        if (currentArea.getLevel() - 1 == 0 || currentArea.getLevel() - 2 == 0) {
            LambdaQueryWrapper<FuncArea> queryWrapper = new LambdaQueryWrapper<>();
            if (currentArea.getLevel() - 1 == 0) {
                response.setRelationTradeNum(this.baseMapper.getRelationTradeNum(id));
                queryWrapper.eq(FuncArea::getPid,id).eq(FuncArea::getIsDeleted,false);
                response.setRelationStreetNum(this.baseMapper.selectCount(queryWrapper));
            }else {
                queryWrapper.eq(FuncArea::getPid,id).eq(FuncArea::getIsDeleted,false);
                response.setRelationTradeNum(this.baseMapper.selectCount(queryWrapper));
            }
        }

        return CommonResponse.success(response);
    }

    /**
     * @Method parentAndPeerInfo
     * @Author zm
     * @Description 父级及同级围栏信息
     * @Date 2024/7/11 13:52
    */
    @Override
    public CommonResponse<FuncAreaParentAndPeerInfoResponse> parentAndPeerInfo(Integer pid) {
        FuncAreaParentAndPeerInfoResponse response = new FuncAreaParentAndPeerInfoResponse();
        String spId = ApplicationUtils.getWorkingSpId();
        System.out.println("spId:"+spId);
        if (null == pid) {
            pid = 0;
        }
        LambdaQueryWrapper<FuncArea> queryWrapper = new LambdaQueryWrapper<>();
        int finalPid = pid;
        queryWrapper.eq(FuncArea::getSpId,spId)
                .eq(FuncArea::getIsDeleted,false)
                .eq(FuncArea::getId, finalPid);
        FuncArea area = this.baseMapper.selectOne(queryWrapper);
        log.info("parentAndPeerInfo:{}",area);
        if (null != area) {
            response.setId(pid);
            response.setFence(area.getFence());
            response.setCenterPoint(area.getCenterPoint());
            if (null != area.getLevel() && area.getLevel() >= 1 && area.getLevel() <= 2) {
                response.setLevel(area.getLevel() + 1);
            }
        }
        return CommonResponse.success(response);
    }

    /**
     * @Method maxOrdinal
     * @Author zm
     * @Description maxOrdinal
     * @Date 2024/7/17 11:32
    */
    @Override
    public CommonResponse<FuncAreaPeerInfoListResponse> maxOrdinal(Integer level) {
        FuncAreaPeerInfoListResponse response = new FuncAreaPeerInfoListResponse();
        String spId = ApplicationUtils.getWorkingSpId();
        FuncArea model = new FuncArea();
        model.setSpId(spId);
        if (null != level && level >=1 && level <= 3) model.setLevel(level);
        response.setMaxOrdinal(this.baseMapper.getFuncAreaMaxOrdinal(model));
        List<FuncAreaPeerInfoResponse> peerList = new ArrayList<>();

        LambdaQueryWrapper<FuncArea> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(FuncArea::getSpId,spId)
                .eq(FuncArea::getIsDeleted,false)
                .eq(FuncArea::getLevel,level)
                .isNotNull(FuncArea::getFence)
                .ne(FuncArea::getFence, "");
        List<FuncArea> list = this.baseMapper.selectList(queryWrapper);
        log.info("list:{}",list);
        if (CollectionUtils.isNotEmpty(list)) {
            peerList = list.stream().map(funcArea -> {
                FuncAreaPeerInfoResponse peer = new FuncAreaPeerInfoResponse();
                BeanUtils.copyProperties(funcArea, peer);
                return peer;
            }).collect(Collectors.toList());
        }
        response.setPeerList(peerList);
        return CommonResponse.success(response);
    }

    /**
     * @Method buildTree
     * @Author zm
     * @Description buildTree
     * @Date 2024/7/9 15:51
    */
    public static List<FuncAreaListResponse> buildTree(List<FuncAreaListResponse> areas) {
        Map<Integer, FuncAreaListResponse> areaMap = new HashMap<>();
        List<FuncAreaListResponse> rootAreas = new ArrayList<>();
        if (CollectionUtils.isEmpty(areas)) return rootAreas;

        for (FuncAreaListResponse area : areas) {
            areaMap.put(area.getId(), area);
            if (area.getPid() == 0) {
                rootAreas.add(area);
            }
        }

        for (FuncAreaListResponse area : areas) {
            if (area.getPid() != 0) {
                FuncAreaListResponse parent = areaMap.get(area.getPid());
                if (parent != null) {
                    if (parent.getChildren() == null) {
                        parent.setChildren(new ArrayList<>());
                    }
                    parent.getChildren().add(area);
                }
            }
        }

        return rootAreas;
    }

    private List<FuncAreaTreeResponse> getAutoTreeList(String spId){
        //所属组织
        List<String> spIds = organizationService.getSpIds(spId);
        List<String> cityCodes = consumerLocationMapper.selectConsumerLocationCityCodes(spIds);
        List<FuncAreaTreeResponse> result = new ArrayList<>();
        if( cityCodes.size()>0 ){
            for (String cityCode:cityCodes) {
                Map<String,AdInfoDTO> adInfoMap = consumerLocationService.getCityAdInfo(cityCode);
                FuncAreaTreeResponse funcAreaTreeResponse = null;
                for (String key:adInfoMap.keySet()){
                    if(!key.contains("_")){
                        funcAreaTreeResponse = new FuncAreaTreeResponse();
                        funcAreaTreeResponse.setFuncCode(key);
                        funcAreaTreeResponse.setFuncName(adInfoMap.get(key).getName());
                        funcAreaTreeResponse.setChilds(getAutoSubTreeList(adInfoMap,"", key));
                    }
                }
                if(ObjectUtil.isNotEmpty(funcAreaTreeResponse)){
                    result.add(funcAreaTreeResponse);
                }
            }
        }
        return result;
    }

    private List<FuncAreaTreeResponse> getAutoSubTreeList(Map<String,AdInfoDTO> adInfoMap,String ppCode, String pCode){
        List<FuncAreaTreeResponse> funcAreaTreeResponses = new ArrayList<>();
        FuncAreaTreeResponse funcAreaTreeResponse;
        for (String key:adInfoMap.keySet()) {
            if (StringUtils.isEmpty(ppCode) && key.contains(pCode+"_") && key.indexOf("_") == key.lastIndexOf("_") ) {
                funcAreaTreeResponse = new FuncAreaTreeResponse();
                funcAreaTreeResponse.setFuncCode(adInfoMap.get(key).getCode());
                funcAreaTreeResponse.setFuncName(adInfoMap.get(key).getName());
                funcAreaTreeResponses.add(funcAreaTreeResponse);
            }else if(StringUtils.isNotEmpty(ppCode) && key.contains(ppCode+"_"+pCode+"_")){
                funcAreaTreeResponse = new FuncAreaTreeResponse();
                funcAreaTreeResponse.setFuncCode(adInfoMap.get(key).getName());
                funcAreaTreeResponse.setFuncName(adInfoMap.get(key).getName());
                funcAreaTreeResponses.add(funcAreaTreeResponse);
            }
        }
        return funcAreaTreeResponses;
    }

    private List<FuncAreaTreeResponse> getTreeList(Map<Integer,List<FuncArea>> funcAreaMap, Integer pid,List<String> funcCodes, List<String> consumerFuncCodes){
        List<FuncArea> pList = funcAreaMap.get(pid);
        List<FuncAreaTreeResponse> list = new ArrayList<>();
        for (FuncArea item1: pList) {
            FuncAreaTreeResponse funcAreaTreeResponse = new FuncAreaTreeResponse();
            BeanUtils.copyProperties(item1,funcAreaTreeResponse);
            if (funcAreaMap.containsKey(item1.getId())) {
                List<FuncAreaTreeResponse> childs= getTreeList(funcAreaMap,item1.getId(),funcCodes,consumerFuncCodes);
                funcAreaTreeResponse.setChilds(childs);
            }
            if(null!=funcCodes && !funcCodes.isEmpty()) {//权限控制
                if (funcCodes.contains(item1.getFuncCode())) {
                    list.add(funcAreaTreeResponse);
                } else if (!consumerFuncCodes.isEmpty() && consumerFuncCodes.contains(item1.getFuncCode())) {//客户数据控制
                    list.add(funcAreaTreeResponse);
                }
            }else{
                list.add(funcAreaTreeResponse);
            }
        }
        return list;
    }


    @Override
    public List<BusinessAreaItemResponse> businessAreaList(BusinessAreaListRequest request) {
        String spId = ApplicationUtils.getWorkingSpId();
        List<BusinessAreaItemResponse> result = new ArrayList<>();

        int page = null==request.getPage()?1:request.getPage();
        int pageSize = null==request.getPageSize()?10:request.getPageSize();

        int start = (page - 1) * pageSize;

        FieldTemplate fieldTemplate = fieldTemplateMapper.getTypeBySpId(spId);

        if( Constants.FUNC_AREA_ALLOCAT_AUTO.equals(fieldTemplate.getFuncAreaAllocat()) ){//自动分配取redis中的行政区数据
            if( StringUtils.isNotEmpty(request.getDistrictCode()) && StringUtils.isNotEmpty(request.getStreetCode())  ){
                Map<String,AdInfoDTO> adInfoMap = consumerLocationService.getCityAdInfo(request.getDistrictCode());
                List<FuncAreaTreeResponse> resp = getAutoSubTreeList(adInfoMap,request.getDistrictCode(),request.getStreetCode());
                for (FuncAreaTreeResponse item:resp) {
                    BusinessAreaItemResponse targetItem = new BusinessAreaItemResponse();
                    BeanUtils.copyProperties(item,targetItem);
                    result.add(targetItem);
                }
            }
            if(result.size()>request.getPage()*request.getPageSize()){
                return result.subList(start,start+request.getPageSize());
            }else{
                return result;
            }
        }else{//自定义分配取自定义的行政区数据
            List<FuncArea> list = this.baseMapper.businessAreaList(spId,request.getFuncCode(),request.getFuncName(),start,request.getPageSize());
            Map<Integer,FuncArea> pFuncAreaMap = getParentFuncArea(list,spId);
            UserFuncCodePermissionDTO userFuncCodePermission = userPermissionService.getUserDepartPermission(
                    ApplicationUtils.getHeaderSpId(),
                    ApplicationUtils.getUserId()
            );
            for (FuncArea funcArea: list) {
                if ( !userFuncCodePermission.getFuncCodes().isEmpty() &&
                        !userFuncCodePermission.getFuncCodes().contains(funcArea.getFuncCode()) ) {
                    continue;
                }
                BusinessAreaItemResponse targetItem = new BusinessAreaItemResponse();
                BeanUtils.copyProperties(funcArea,targetItem);
                if ( null!=funcArea.getPid() && funcArea.getPid()>0 && pFuncAreaMap.containsKey(funcArea.getPid()) ){
                    FuncArea pFuncArea = pFuncAreaMap.get(funcArea.getPid());
                    if( 2 == pFuncArea.getLevel() ){//街道
                        targetItem.setPStreetCode(pFuncArea.getFuncCode());
                        if (pFuncArea.getPid()>0 && pFuncAreaMap.containsKey(pFuncArea.getPid())){
                            targetItem.setPDistrictCode(pFuncAreaMap.get(pFuncArea.getPid()).getFuncCode());
                        }
                    }else if( 1 == pFuncArea.getLevel() ){//区
                        targetItem.setPDistrictCode(pFuncArea.getFuncCode());
                    }
                }
                result.add(targetItem);
            }
            return result;
        }
    }

    private Map<Integer,FuncArea> getParentFuncArea(List<FuncArea> list,String spId){
        Map<Integer, FuncArea> ret = new HashMap<>();
        try {
            List<Integer> pids = list.stream().map(FuncArea::getPid)
                    .filter(pid -> pid != 0)
                    .distinct().
                    collect(Collectors.toList());
            if (!pids.isEmpty()) {
                LambdaQueryWrapper<FuncArea> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(FuncArea::getSpId, spId);
                queryWrapper.eq(FuncArea::getIsDeleted, false);
                queryWrapper.in(FuncArea::getId, pids);
                List<FuncArea> nList = this.baseMapper.selectList(queryWrapper);
                for (FuncArea item : nList) {
                    ret.put(item.getId(), item);
                }
                Map<Integer, FuncArea> pMap = getParentFuncArea(nList, spId);
                if (!pMap.isEmpty()) {
                    ret.putAll(pMap);
                }
            }
        }catch (Exception e){
            log.error("获取商圈的父级机构失败",e);
            ret = new HashMap<>();
        }
        return ret;
    }

    @Override
    public Map<String, AdInfoDTO> getFuncAreaMapByCode() {
        String spId = ApplicationUtils.getWorkingSpId();
        LambdaQueryWrapper<FuncArea> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(FuncArea::getSpId,spId);
        queryWrapper.eq(FuncArea::getIsDeleted,false);
        List<FuncArea> list = this.baseMapper.selectList(queryWrapper);
        if(list.isEmpty()){
            return new HashMap<>();
        }
        //级别 1：功能区 2：街道 3：商圈
        //city:市，district:区县, street:街道
        Map<Integer,String> levelMap = new HashMap<>();
        levelMap.put(1,"city");
        levelMap.put(2,"district");
        levelMap.put(3,"street");
        Map<String,AdInfoDTO> result = new HashMap<>();
        for (FuncArea funcArea:list){
            AdInfoDTO adInfoDTO = new AdInfoDTO();
            adInfoDTO.setCode(funcArea.getFuncCode());
            adInfoDTO.setName(funcArea.getFuncName());
            if( levelMap.containsKey(funcArea.getLevel()) ){
                adInfoDTO.setLevel(levelMap.get(funcArea.getLevel()));
            }
            adInfoDTO.setCenter(funcArea.getCenterPoint());
            adInfoDTO.setFence(funcArea.getFence());
            result.put(funcArea.getFuncCode(), adInfoDTO);
        }
        return result;
    }

    @Override
    public Map<String, FuncArea> getFuncAreaMapByCode(Integer level) {
        String spId = ApplicationUtils.getWorkingSpId();
        LambdaQueryWrapper<FuncArea> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(FuncArea::getSpId,spId);
        if (null!=level){
            queryWrapper.eq(FuncArea::getLevel,level);
        }
        queryWrapper.eq(FuncArea::getIsDeleted,false);
        List<FuncArea> list = this.baseMapper.selectList(queryWrapper);
        if(list.isEmpty()){
            return new HashMap<>();
        }
        return list.stream().collect(Collectors.toMap(FuncArea::getFuncCode,funcArea -> funcArea));
    }

    @Override
    public Map<Integer, FuncArea> getFuncAreaMapById(Integer level) {
        String spId = ApplicationUtils.getWorkingSpId();
        LambdaQueryWrapper<FuncArea> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(FuncArea::getSpId,spId);
        if (null!=level){
            queryWrapper.eq(FuncArea::getLevel,level);
        }
        queryWrapper.eq(FuncArea::getIsDeleted,false);
        List<FuncArea> list = this.baseMapper.selectList(queryWrapper);
        if(list.isEmpty()){
            return new HashMap<>();
        }
        return list.stream().collect(Collectors.toMap(FuncArea::getId,funcArea -> funcArea));
    }

    @Override
    public Map<String, FuncArea> getFuncAreaMapByName() {
        String spId = ApplicationUtils.getWorkingSpId();
        LambdaQueryWrapper<FuncArea> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(FuncArea::getSpId,spId);
        queryWrapper.eq(FuncArea::getIsDeleted,false);
        List<FuncArea> list = this.baseMapper.selectList(queryWrapper);
        if( list.size() == 0 ){
            return null;
        }
        return list.stream().collect(Collectors.toMap(FuncArea::getFuncName,funcArea -> funcArea));
    }

    @Override
    public List<FuncAreaLevelResponse> getLevels(){
        String spId = ApplicationUtils.getWorkingSpId();
        UserFuncCodePermissionDTO userFuncCodePermission = userPermissionService.getUserDepartPermission(spId,ApplicationUtils.getUserId());
        return getPermissionLevel(userFuncCodePermission);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void syncArea() {
        int pageIndex = 1;
        int  pageSize = 500;
        long total = 0;
        do{
            Page<FuncArea> pages = PageHelper.startPage(pageIndex, pageSize);
            QueryWrapper<FuncArea> areaQueryWrapper = new QueryWrapper<>();
            areaQueryWrapper.lambda().eq(FuncArea::getIsDeleted, false);
            List<FuncArea> funcAreas = this.list(areaQueryWrapper);
            pageIndex++;
            total = pages.getTotal();
            log.info("区域表高德转百度{},分页{},{}，{}",pageIndex, pages.getPages(), pages.getPageSize(), pages.getTotal());
            if (org.apache.commons.collections.CollectionUtils.isNotEmpty(funcAreas)) {
                //开始修改坐标
                for (FuncArea funcArea : funcAreas) {
                    if (StringUtils.isNotEmpty(funcArea.getFence())) {
                        List<BaiDuDetailResp> baiDuDetailResps = CoordinatesTransitionUtil.requestGetAK(funcArea.getFence(), baiDuMapsKey);
                        StringBuffer sb = new StringBuffer();
                        if (CollectionUtils.isNotEmpty(baiDuDetailResps)) {
                            for (BaiDuDetailResp baiDuDetailResp : baiDuDetailResps) {
                                sb.append(baiDuDetailResp.getX()).append(",").append(baiDuDetailResp.getY()).append(";");
                            }
                        }
                        if (sb.length() > 0) {
                            String fence = sb.toString().substring(0, sb.toString().length() - 1);
                            funcArea.setFence(fence);
                            Polygon currentPolygon = createPolygonFromCoordinates(fence);
                            funcArea.setBoundaryStr(currentPolygon.toString());
                        }
                    }
                    if (StringUtils.isNotEmpty(funcArea.getCenterPoint())) {
                        List<BaiDuDetailResp> baiDuDetailResps = CoordinatesTransitionUtil.requestGetAK(funcArea.getCenterPoint(), baiDuMapsKey);
                        if (CollectionUtils.isNotEmpty(baiDuDetailResps)) {
                            funcArea.setCenterPoint(baiDuDetailResps.get(0).getX() + "," + baiDuDetailResps.get(0).getY());
                        }
                    }
                }
                this.saveOrUpdateBatch(funcAreas);
            }
            funcAreas.clear();
        }while(total > (pageIndex - 1) * pageSize);
    }

    /**
     * 获取权限关联的级别
     * @param userFuncCodePermission
     * @return
     */
    public List<FuncAreaLevelResponse> getPermissionLevel(UserFuncCodePermissionDTO userFuncCodePermission){
        List<FuncAreaLevelResponse> ret = new ArrayList<>();
        FuncAreaLevelResponse lvl3 = new FuncAreaLevelResponse();
        lvl3.setName("商圈");
        lvl3.setLevel(3);
        FuncAreaLevelResponse lvl2 = new FuncAreaLevelResponse();
        lvl2.setName("街道");
        lvl2.setLevel(2);
        FuncAreaLevelResponse lvl1 = new FuncAreaLevelResponse();
        lvl1.setName("功能区");
        lvl1.setLevel(1);
        if( userFuncCodePermission.getAuthority()!=1 ){
            ret.add(lvl3);
            ret.add(lvl2);
            ret.add(lvl1);
        }else if(null!=userFuncCodePermission.getFuncIds() && !userFuncCodePermission.getFuncIds().isEmpty()){
            List<FuncArea> list = this.baseMapper.selectBatchIds(userFuncCodePermission.getFuncIds());
            boolean hasLvl1 = false;
            boolean hasLvl2 = false;
            for (FuncArea item:list){
                if(item.getLevel()==1){
                    hasLvl1 = true;
                }else if(item.getLevel()==2){
                    hasLvl2 = true;
                }
            }
            if (hasLvl1){
                ret.add(lvl2);
                ret.add(lvl3);
            }else if(hasLvl2){
                ret.add(lvl3);
            }
        }
        return ret;
    }
}
